package org.yxt.message.push.config;

import com.alibaba.fastjson.serializer.SerializerFeature;
import com.alibaba.fastjson.support.config.FastJsonConfig;
import com.alibaba.fastjson.support.spring.FastJsonHttpMessageConverter;
import org.springframework.boot.web.servlet.MultipartConfigFactory;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.Ordered;
import org.springframework.http.MediaType;
import org.springframework.http.converter.HttpMessageConverter;
import org.springframework.http.converter.StringHttpMessageConverter;
import org.springframework.util.unit.DataSize;
import org.springframework.web.servlet.config.annotation.CorsRegistry;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;
import org.springframework.web.servlet.config.annotation.ViewControllerRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
import org.springframework.web.servlet.view.freemarker.FreeMarkerViewResolver;

import javax.servlet.MultipartConfigElement;
import java.nio.charset.Charset;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

/**
 * 系统拦截器及资源配置
 * 所有web配置
 *
 * @author helloWorld
 * <p>
 * 2018年10月20日
 */
@Configuration
public class WebMvcConfigurerAdapter implements WebMvcConfigurer {

    /**
     * 文件上传主目录映射
     */
    public final String UPLOAD_FILE_MAIN_PATH = "/upload_file/";
    /**
     * 文件上传存储本地文件目录 /home/zyserver2/tianyijinrong
     */
    public static final String UPLOAD_FILE_MAIN_LOC_PATH = "D:\\";

    /**
     * 拦截session
     *
     * @param registry
     */
    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        // 指定该拦截器不拦截目录
        registry.addInterceptor(new SessionInterceptor()).excludePathPatterns(Arrays.asList("/static/**", "/static/css/*", "/static/images/*"));
    }

    /**
     * 默认访问根目录转发
     *
     * @param registry
     */
    @Override
    public void addViewControllers(ViewControllerRegistry registry) {
        //访问项目统一转发index.ftl
        registry.addViewController("/").setViewName("index");
        registry.setOrder(Ordered.HIGHEST_PRECEDENCE);
    }

    /**
     * 跨域配置
     *
     * @param registry
     */
    @Override
    public void addCorsMappings(CorsRegistry registry) {
        registry.addMapping("/**");
    }

    /**
     * 配置静态资源访问
     * addResourceHandler 暴露的访问地址
     * addResourceLocations 文件存放位置
     * http://localhost:8080/static/1.jpg
     *
     * @param registry
     */
    @Override
    public void addResourceHandlers(ResourceHandlerRegistry registry) {
        registry.addResourceHandler(UPLOAD_FILE_MAIN_PATH.concat("**")).addResourceLocations("file:".concat(UPLOAD_FILE_MAIN_LOC_PATH).concat(UPLOAD_FILE_MAIN_PATH));
        // 静态文件只要访问就代理到本地
        registry.addResourceHandler("/static/**").addResourceLocations("classpath:/static/");
        // Swagger2 页面访问不到问题
        registry.addResourceHandler("doc.html").addResourceLocations("classpath:/META-INF/resources/");
        registry.addResourceHandler("/webjars/**").addResourceLocations("classpath:/META-INF/resources/webjars/");
        registry.addResourceHandler("swagger-ui.html").addResourceLocations("classpath:/META-INF/resources/");
        registry.addResourceHandler("/webjars/**").addResourceLocations("classpath:/META-INF/resources/webjars/");
        // Swagger2 页面访问不到问题 end
        // 解决其他静态文件无法读取
        registry.addResourceHandler("/**").addResourceLocations("classpath:/static/");
        registry.addResourceHandler("/**").addResourceLocations("classpath:/resources/");
        registry.addResourceHandler("/**").addResourceLocations("classpath:/META-INF/resources/");
    }

    /**
     * 加对Freemarker支持
     *
     * @return
     */
    @Bean
    public FreeMarkerViewResolver freeMarkerViewResolver() {
        FreeMarkerViewResolver freeMarkerViewResolver = new FreeMarkerViewResolver();
        freeMarkerViewResolver.setCache(false);
        freeMarkerViewResolver.setPrefix("/");
        freeMarkerViewResolver.setSuffix(".html");
        freeMarkerViewResolver.setRequestContextAttribute("request");
        // 启用顺序
        freeMarkerViewResolver.setOrder(1);
        freeMarkerViewResolver.setContentType("text/html;charset=UTF-8");
        return freeMarkerViewResolver;
    }

    /**
     * html解析器 不使用
     *
     * @return

     @Bean public InternalResourceViewResolver htmlViewResolver() {
     InternalResourceViewResolver viewResolver = new InternalResourceViewResolver();
     viewResolver.setPrefix("/");
     viewResolver.setSuffix(".html");
     viewResolver.setCache(false);
     // 启用顺序
     viewResolver.setOrder(1);
     viewResolver.setContentType("text/html;charset=UTF-8");
     return viewResolver;
     }*/

    /**
     * JSP解析器
     *
     * @return

     @Bean public InternalResourceViewResolver jspViewResolver() {
     InternalResourceViewResolver viewResolver = new InternalResourceViewResolver();
     viewResolver.setPrefix("/WEB-INF/");
     viewResolver.setSuffix(".jsp");
     // 启用顺序
     viewResolver.setOrder(2);
     viewResolver.setContentType("text/html;charset=UTF-8");
     return viewResolver;
     }*/

    /**
     * 修改StringHttpMessageConverter默认配置 使用fastJson 默认转换
     * 强制使用fast json作为数据json转换
     *
     * @param converters
     */
    @Override
    public void configureMessageConverters(List<HttpMessageConverter<?>> converters) {
        // 1.定义一个converters转换消息的对象
        FastJsonHttpMessageConverter fastConverter = new FastJsonHttpMessageConverter();
        // 2.添加fastjson的配置信息，比如: 是否需要格式化返回的json数据
        FastJsonConfig fastJsonConfig = new FastJsonConfig();
        // 防止多级引用后 $ref
        fastJsonConfig.setSerializerFeatures(
                SerializerFeature.PrettyFormat,
                SerializerFeature.DisableCircularReferenceDetect);
        //此处是全局处理方式
        fastJsonConfig.setDateFormat("yyyy-MM-dd HH:mm:ss");
        // 解决中文乱码问题：在方法内部添加这段代码
        List<MediaType> fastMediaTypes = new ArrayList<>();
        fastMediaTypes.add(MediaType.APPLICATION_JSON);
        fastConverter.setSupportedMediaTypes(fastMediaTypes);
        // 处理字符串, 避免直接返回字符串的时候被添加了引号
        StringHttpMessageConverter stringHttpMessageConverter = new StringHttpMessageConverter(Charset.forName("UTF-8"));
        // 3.在converter中添加配置信息
        fastConverter.setFastJsonConfig(fastJsonConfig);
        // 4.将converter赋值给HttpMessageConverter
        HttpMessageConverter<?> converter = fastConverter;
        converters.add(converter);
        converters.add(stringHttpMessageConverter);
    }

    /**
     * 文件上传配置
     *
     * @return
     */
    @Bean
    public MultipartConfigElement multipartConfigElement() {
        MultipartConfigFactory factory = new MultipartConfigFactory();
        //文件最大
        factory.setMaxFileSize(DataSize.ofKilobytes(1024)); //KB,MB
        /// 设置总上传数据总大小
        factory.setMaxRequestSize(DataSize.ofMegabytes(1024));
        return factory.createMultipartConfig();
    }

}
